package com.cn.bean;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Date;
import java.util.HashMap;

import net.sf.json.JSONObject;

import com.cn.xc.utils.BeanUtil;
import com.cn.xc.utils.ObjectUtil;

/**
 * FUN: 简单封装下map
 *
 * @author sushy
 * @date 2016-3-23 
 */
public class SimpleMap extends HashMap<String, Object> {

	private static final long serialVersionUID = 6498903674644767830L;

	public SimpleMap() {
		super();
	}

	public SimpleMap(int initialCapacity) {
		super(initialCapacity);
	}

	/**
	 * 复制属性
	 * 
	 * @param objBean
	 * @return
	 */
	public static SimpleMap toMap(Object objBean) {
		SimpleMap map = new SimpleMap();
		map.copyProperties(objBean);
		return map;
	}

	/**
	 * 复制属性
	 * 
	 * @param objBean
	 * @return
	 */
	public static void fromMap(Object objBean, SimpleMap map) {
		map.saveProperties(objBean);
	}

	/**
	 * Bean属性装载到Map容器
	 * 
	 * @param objBean
	 * @return
	 */
	public void saveProperties(Object objBean) {
		if (objBean == null) {
			return;
		}

		Class<?> cls = objBean.getClass();
		PropertyDescriptor targetPds[] = BeanUtil.getPropertyDescriptors(cls);
		for (int i = 0; i < targetPds.length; ++i) {
			PropertyDescriptor targetPd = targetPds[i];
			if ("class".equals(targetPd.getName())) {
				continue;
			}
			if (targetPd.getWriteMethod() == null) {
				continue;
			}

			Object value = get(targetPd.getName());
			if (value == null) {
				continue;
			}

			if (value instanceof String) {
				if (((String) value).length() <= 0
						|| targetPd.getPropertyType() != String.class) {
					continue;
				}
			}

			try {
				Method writeMethod = targetPd.getWriteMethod();
				if (!Modifier.isPublic(writeMethod.getDeclaringClass()
						.getModifiers())) {
					writeMethod.setAccessible(true);
				}
				writeMethod.invoke(objBean, new Object[] { value });
			} catch (Throwable ex) {
				throw new RuntimeException(
						"Could not copy properties from source to target", ex);
			}
		}
	}

	/**
	 * 复制属性
	 * 
	 * @param objBean
	 * @return
	 */
	public void copyProperties(Object objBean) {
		if (objBean == null) {
			return;
		}

		Class<?> cls = objBean.getClass();
		PropertyDescriptor pds[] = BeanUtil.getPropertyDescriptors(cls);
		for (int i = 0; i < pds.length; i++) {
			PropertyDescriptor pd = pds[i];
			if ("class".equals(pd.getName())) {
				continue;
			}
			
			try {
				Method readMethod = pd.getReadMethod();
				if (!Modifier.isPublic(readMethod.getDeclaringClass()
						.getModifiers())) {
					readMethod.setAccessible(true);
				}

				Object value = readMethod.invoke(objBean, new Object[0]);
				if (value == null) {
					value = "";
				}

				put(pd.getName(), value);
			} catch (Throwable ex) {
				throw new RuntimeException(
						"Could not copy properties from source to target", ex);
			}
		}
	}

	public int getInt(String key) {
		return getInt(key, 0);
	}

	public int getInt(String key, int defaultValue) {
		Object obj = get(key);
		return ObjectUtil.toInt(obj, defaultValue);
	}

	public long getLong(String key) {
		return getLong(key, 0);
	}

	public long getLong(String key, long defaultValue) {
		Object obj = get(key);
		return ObjectUtil.toLong(obj, defaultValue);
	}

	public double getDouble(String key) {
		return getDouble(key, 0);
	}

	public double getDouble(String key, double defaultValue) {
		Object obj = get(key);
		return ObjectUtil.toDouble(obj, defaultValue);
	}

	public String getString(String key) {
		return getString(key, "");
	}

	public String getString(String key, String defaultValue) {
		Object obj = get(key);
		return ObjectUtil.toString(obj, defaultValue);
	}

	public Date getDate(String key) {
		Object obj = get(key);
		return ObjectUtil.toDate(obj);
	}

	public SimpleMap set(String key, Object value) {
		return this.put(key, value);
	}

	public SimpleMap put(String key, Object value) {
		super.put(key, value);
		return this;
	}

	public JSONObject toJson() {
		return JSONObject.fromObject(this);
	}

	public String toJsonString() {
		return toJson().toString();
	}

}
